<html>
<head>
<link rel="shortcut icon" href="./favicon.ico">
<link rel="stylesheet" type="text/css" href="./style.css">
<link rel="canonical" href="./Pipeline_Join_Lazy.html">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="Takes in multiple input ready/valid handshakes with associated data, and once all input handshakes can complete, joins them together into a single output ready/valid handshake with all data concatenated. This function synchronizes multiple pipelines into a single wider one.">
<title>Pipeline Join Lazy</title>
</head>
<body>

<p class="inline bordered"><b><a href="./Pipeline_Join_Lazy.v">Source</a></b></p>
<p class="inline bordered"><b><a href="./legal.html">License</a></b></p>
<p class="inline bordered"><b><a href="./index.html">Index</a></b></p>

<h1>Pipeline Join (Lazy)</h1>
<p>Takes in multiple input ready/valid handshakes with associated data, and
 once all input handshakes can complete, joins them together into a single
 output ready/valid handshake with all data concatenated. This function
 synchronizes multiple pipelines into a single wider one.</p>
<h2>Avoiding combinational loops</h2>
<p>As a design convention, we must avoid a combinational path between the
 valid and ready signals in a given pipeline interface, because if the other
 end of the pipeline connection also has a ready/valid combinational path,
 connecting these two interfaces will form a combinational loop, which
 cannot be analyzed for timing, or simulated reliably.</p>
<p>However, there are rare cases where you do <em>not</em> want buffering, so if you
 take care about combinational delays and loops, you can use this unbuffered
 version. Otherwise, use the regular buffered [Pipeline Join]
 (./Pipeline_Join.html).</p>

<pre>
`default_nettype none

module <a href="./Pipeline_Join_Lazy.html">Pipeline_Join_Lazy</a>
#(
    parameter WORD_WIDTH     = 0,
    parameter INPUT_COUNT    = 0,

    // Do not set at instantiation, except in IPI
    parameter TOTAL_WIDTH   = WORD_WIDTH * INPUT_COUNT
)
(
    input  wire [INPUT_COUNT-1:0]   input_valid,
    output reg  [INPUT_COUNT-1:0]   input_ready,
    input  wire [TOTAL_WIDTH-1:0]   input_data,

    output reg                      output_valid,
    input  wire                     output_ready,
    output reg  [TOTAL_WIDTH-1:0]   output_data
);

    localparam INPUT_ZERO = {INPUT_COUNT{1'b0}};
    localparam INPUT_ONES = {INPUT_COUNT{1'b1}};
    localparam TOTAL_ZERO = {TOTAL_WIDTH{1'b0}};

    initial begin
        input_ready  = INPUT_ZERO;
        output_valid = 1'b0;
        output_data  = TOTAL_ZERO;
    end
</pre>

<p>Once all inputs are valid, declare the output valid and make all the input
 ready equal to the output ready.  Pass the input data to the output data.</p>

<pre>
    always @(*) begin
        output_valid    = (input_valid == INPUT_ONES);
        output_data     = input_data;
    end

    always @(*) begin
        input_ready     = (output_valid == 1'b1) ? {INPUT_COUNT{output_ready}} : INPUT_ZERO;
    end

endmodule
</pre>

<hr>
<p><a href="./index.html">Back to FPGA Design Elements</a>
<center><a href="https://fpgacpu.ca/">fpgacpu.ca</a></center>
</body>
</html>

